<template>
  <a-drawer
    title="创作脚本"
    :width="750"
    :visible="visible"
    :footer-style="{ textAlign: 'right' }"
    @close="handleClose"
  >
    <a-form
      :model="scriptForm"
      :label-col="{ span: 4 }"
      :wrapper-col="{ span: 16 }"
    >
      <a-form-item label="脚本名称" name="title">
        <a-input
          placeholder="请输入脚本名称"
          v-model:value="scriptForm.title"
        />
      </a-form-item>
      <a-form-item label="音频配置" name="config">
        <span>{{ audioConfig?.name }}</span>
        <a-button
          type="link"
          style="margin-left: 10px"
          @click="handleAudioConfig"
          >编辑</a-button
        >
      </a-form-item>
      <a-form-item label="场景音频配置" name="sence">
        <a-radio-group
          @change="handleRadioChange"
          v-model:value="scriptForm.subtitle_status"
          name="radioGroup"
        >
          <a-radio value="on">开启</a-radio>
          <a-radio value="off">关闭</a-radio>
        </a-radio-group>
        <a-button style="margin-left: 10px" type="link" @click="handleSubTitle"
          >字幕效果</a-button
        >
      </a-form-item>
    </a-form>

    <div class="form_con">
      <div class="form_title">脚本内容</div>
      <div class="form_desc">
        脚本一般由多个场景组成，场景内可添加台词（及生成的音频）和视频等内容
      </div>
    </div>

    <a-card
      style="width: 95%; margin-left: 10px; margin-top: 10px"
      v-for="(item, index) in cardList"
      :key="index"
    >
      <template #title>
        <div class="card_title">
          <MenuOutlined style="cursor: move" />
          <span style="margin-left: 5px; font-size: 14px; color: #999"
            >场景名称</span
          >
          <a-input
            style="width: 120px; margin-left: 5px"
            placeholder="如: 项目门头"
            v-model:value="cardList[index].scene_name"
          />
        </div>
      </template>
      <template #extra>
        <div class="scene_time">
          <span>场景时长</span>
          <a-radio-group
            style="margin-left: 10px"
            v-model:value="cardList[index].scene_type"
            name="radioGroup"
          >
            <a-radio :value="0">自动</a-radio>
            <a-radio :value="1">固定</a-radio>
          </a-radio-group>
          <a-input-number
            :min="0"
            :max="999999"
            :step="0.5"
            :precision="1"
            v-if="cardList[index].scene_type == 1"
            style="width: 120px"
            placeholder="请输入时长:秒"
            v-model:value="cardList[index].scene_time"
          />
          <a-button style="color: red" type="link" @click="deleteCard(index)"
            >删除</a-button
          >
        </div>
      </template>

      <div class="card_content">
        <div class="content_name">场景描述（选填）</div>
        <div class="content_con">
          <a-textarea
            show-count
            :maxlength="50"
            style="margin-top: 5px"
            v-model:value="cardList[index].scene_desc"
            placeholder="如 这个场景体现了项目的门头"
            :auto-size="{ minRows: 2, maxRows: 2 }"
          />
        </div>
        <div
          class="bottom_btn"
          style="border-top: 1px solid #eee; padding: 10px 0; margin-top: 20px"
        >
          <div class="lines_con" v-if="item?.items?.length">
            <div class="content_title">台词</div>
            <div class="content_txt">场景音频</div>
          </div>
          <div
            class="lines_item"
            v-for="(lines_item, lines_index) in item?.items"
            :key="lines_index"
          >
            <div class="left_lines_content">
              <a-tooltip>
                <template #title>{{ lines_item.content }}</template>
                {{ lines_item.content }}
              </a-tooltip>
            </div>
            <div class="lines_contact_icon">
              <cu-icon
                style="color: #999; font-size: 20px"
                type="icon-lianjie"
              />
            </div>
            <div class="right_lines_audio">
              <div class="left_player_icon">
                <cu-icon
                  @click="previewAudio(lines_item)"
                  style="color: #666; font-size: 17px; cursor: pointer"
                  type="icon-bofang"
                />
                <div class="duration" v-if="lines_item?.duration_text">
                  {{ lines_item?.duration_text }}
                </div>
                <div class="duration" v-else>
                  未生成，点击<a
                    style="color: #2878ff"
                    @click="generateAudio(lines_item, lines_index, index)"
                    >生成</a
                  >
                </div>
              </div>
              <div class="right_set_icon">
                <a-popover overlayClassName="popover_con" placement="bottom">
                  <template #content>
                    <div class="pop_operate_con">
                      <a-button
                        style="color: #fff"
                        type="link"
                        @click="addThisLines(lines_item, lines_index, index)"
                        >编辑</a-button
                      >
                      <a-button
                        style="color: #fff"
                        type="link"
                        @click="deleteLines(lines_index, index)"
                        >删除</a-button
                      >
                    </div>
                  </template>
                  <cu-icon
                    style="color: #666; font-size: 17px"
                    type="icon-shezhi"
                  />
                </a-popover>
              </div>
            </div>
          </div>
          <a-button
            style="margin-top: 10px"
            @click="addThisLines(null, null, index)"
          >
            <template #icon>
              <PlusOutlined />
            </template>
            添加台词
          </a-button>
        </div>
      </div>
    </a-card>

    <div class="form_con" style="margin-top: 20px">
      <a-button type="primary" @click="addCard">
        <template #icon>
          <PlusOutlined />
        </template>
        添加场景
      </a-button>
    </div>
    <subtitleSettings :visible="subTitleVisible" @close="closeSubTitle" />
    <!-- 音频配置 -->
    <AddDubbing :visible="visibleDubbing" @saveAudio="getAudioConfig" />
    <addLines
      :visible="linesVisible"
      :linesDetail="linesDetail"
      @close="closeLines"
    />
    <PreviewModal
      :type="previewObj.type"
      :visible="previewObj.visible"
      :url="previewObj.url"
      :title="previewObj.title"
      @onCancel="closePreview"
    />
    <template #footer>
      <a-space>
        <a-button @click="handleClose">取消</a-button>
        <a-button :loading="submitLoading" type="primary" @click="handleOk"
          >保存并使用</a-button
        >
      </a-space>
    </template>
  </a-drawer>
</template>

<script>
import { PlusOutlined, MenuOutlined } from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import { toRefs, defineComponent, reactive, ref, watch, computed } from "vue";
import AddDubbing from "./AddDubbing.vue";
import subtitleSettings from "./scriptSubtitle.vue";
import addLines from "./addLines.vue";
import store from "@/store";
import request from "../../../../../../common/utils/request";
import PreviewModal from "@/components/PreviewModal/index.vue";
export default defineComponent({
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    scriptDetail: {
      type: Object,
      default: () => {
        return {};
      },
    },
    script_line_tag_id: {
      type: [Number, String],
      default: 0,
    },
  },
  emits: ["close"],
  components: {
    PlusOutlined,
    MenuOutlined,
    AddDubbing,
    subtitleSettings,
    addLines,
    PreviewModal,
  },
  setup(props, context) {
    const state = reactive({
      audioConfig: {},
      scriptForm: {
        script_type: "user",
        title: "",
        subtitle_status: "on",
        audio_config: {},
        subtitle_config: {},
        script_scenes: [],
        script_line_tag_id: null,
      },
      cardList: [
        {
          scene_name: null,
          scene_type: 0,
          scene_time: null,
          scene_desc: "",
        },
      ],
      visibleDubbing: false,
      subTitleVisible: false,
      linesVisible: false,
      linesDetail: {},
      submitLoading: false,
      previewObj: {
        type: "audo",
        visible: false,
        url: "",
        title: "",
      },
      isRequesting: false,
    });

    const handleClose = () => {
      context.emit("close");
    };

    const deleteCard = (index) => {
      if (state.cardList.length == 1) {
        message.warn("至少有一个场景");
        return;
      }
      state.cardList.splice(index, 1);
    };

    const handleAudioConfig = () => {
      state.visibleDubbing = true;
    };

    const getAudioConfig = (obj) => {
      state.visibleDubbing = false;
      if (obj) {
        let name =
          obj?.audio?.human_style +
          "（" +
          obj?.audio?.emotion_style.find(
            (item) => item.key == obj.emotion_category
          ).value +
          "）";
        state.audioConfig = {
          speed: obj.speed,
          volume: obj.volume,
          voice_id: obj.audio.id,
          voice_type: obj.audio.timbre_id,
          gender_type: obj.audio.gender,
          emotion_category: obj.emotion_category,
          emotion_intensity: obj.emotion_intensity,
          emotion_style_key: obj.emotion_category,
          name: name,
        };
      }
    };

    const handleRadioChange = () => {};

    const handleSubTitle = () => {
      if (state.scriptForm.subtitle_status == "off") return;
      state.subTitleVisible = true;
    };

    const closeSubTitle = (obj) => {
      state.subTitleVisible = false;
    };

    const addCard = () => {
      state.cardList.push({
        scene_name: null,
        scene_type: 0,
        scene_time: null,
        scene_desc: "",
      });
    };

    const closeLines = (obj) => {
      state.linesVisible = false;
      state.linesDetail = {};
      if (obj) {
        if (!state.cardList[obj.index]["items"]) {
          state.cardList[obj.index]["items"] = [];
          state.cardList[obj.index]["items"].push(obj);
        } else if (obj.lines_index || obj.lines_index == 0) {
          state.cardList[obj.index]["items"][obj.lines_index] = obj;
        } else {
          state.cardList[obj.index]["items"].push(obj);
        }
      }
    };

    const addThisLines = (lines_item, lines_index, index) => {
      if (!lines_item) {
        state.linesVisible = true;
        state.linesDetail["index"] = index;
        return;
      }
      state.linesDetail = lines_item;
      state.linesDetail["lines_index"] = lines_index;
      state.linesDetail["index"] = index;
      state.linesVisible = true;
    };

    const deleteLines = (lines_index, index) => {
      state.cardList[index]["items"].splice(lines_index, 1);
    };

    const handleOk = () => {
      state.scriptForm.audio_config = state.audioConfig;
      state.scriptForm.script_scenes = [];
      state.cardList.map((card_item, card_index) => {
        let card_obj = {};
        card_obj.sn = card_index;
        card_obj.name = card_item.scene_name;
        card_obj.seconds_type = card_item.scene_type;
        if (card_item.scene_type == 0) {
          card_obj.seconds = 5;
        } else {
          card_obj.seconds = card_item.scene_time;
        }
        card_obj.remark = card_item.scene_desc;
        card_obj.video = [];
        card_obj.line_audio = card_item.items;
        state.scriptForm.script_scenes.push(card_obj);
      });

      state.submitLoading = true;

      let request_url = "/user/shotstack/script-line/add";
      let request_method = "post";
      if (state.scriptForm.id) {
        request_url = "/user/shotstack/script-line/update";
        request_method = "put";
      }
      request[request_method]("/work_ai", request_url, state.scriptForm)
        .then((res) => {
          context.emit("close");
          state.submitLoading = false;
          let scriptParams = {
            title: state.scriptForm.title,
            audio_config: state.scriptForm.audio_config,
            subtitle_config: state.scriptForm.subtitle_config,
            subtitle_status: state.scriptForm.subtitle_status,
          };
          store.dispatch("SetScriptData", scriptParams);
          let resource_data = [];
          state.cardList.map((item, index) => {
            resource_data.push({
              sn: index,
              name: item.scene_name,
              video: [],
              remark: item.scene_desc,
              items: item.items,
              seconds_type: item.seconds_type,
              seconds: item.seconds,
              script_line_id: props?.scriptDetail?.id,
            });
          });
          store.dispatch("SetClipJSONResourceData", resource_data);
          if (request_method == "post") {
            message.success("添加成功！");
          } else {
            message.success("更新成功！");
          }
        })
        .catch((err) => {
          state.submitLoading = false;
        });
    };

    const generateAudio = (lines_item, lines_index, index) => {
      if (state.isRequesting) {
        message.warn("正在生成中，请稍等...");
        return;
      }
      state.isRequesting = true;
      request
        .post("/work_ai", "/user/shotstack/text-to-audio", {
          content: lines_item.content,
          volume: 0,
          speed: 1,
          voice_type: "https://cloud.tencent.com/document/product/1073/92668",
          emotion_category: "neutral",
          emotion_intensity: 100,
        })
        .then((res) => {
          state.isRequesting = false;
          Object.assign(
            state.cardList[index]["items"][lines_index],
            res.result
          );
          message.success("生成成功！");
        })
        .catch((err) => {});
    };

    const previewAudio = (item) => {
      state.previewObj = {
        type: "audio",
        url: item.audio_url,
        title: "预览-" + item.content,
        visible: true,
      };
    };

    const closePreview = () => {
      state.previewObj = {
        type: "audio",
        url: "",
        title: "",
        visible: false,
      };
    };

    watch(
      () => props.visible,
      (val) => {
        if (val && props.scriptDetail) {
          const { audio_config, script_scenes } = props.scriptDetail;
          state.audioConfig = audio_config;
          state.scriptForm = {
            id: props.scriptDetail?.id,
            script_type: "user",
            title: props.scriptDetail?.title,
            subtitle_status: props.scriptDetail?.subtitle_status,
            audio_config: audio_config,
            subtitle_config: {},
            script_scenes: [],
            script_line_tag_id: props.scriptDetail?.script_line_tag_id,
          };
          if (script_scenes?.length) {
            state.cardList = [];
            script_scenes.map((item) => {
              state.cardList.push({
                scene_name: item.name,
                scene_type: item.seconds_type,
                scene_time: item.seconds,
                scene_desc: item.remark,
                items: item.line_audio,
              });
            });
          }
        }
        if (val && props.script_line_tag_id) {
          let audio_config = store.getters.clipJSON?.script_data?.audio_config;
          let subtitle_config =
            store.getters.clipJSON?.script_data?.subtitle_config;
          state.scriptForm["audio_config"] = audio_config;
          state.audioConfig = audio_config;
          state.scriptForm.subtitle_status = "on";
          state.scriptForm["subtitle_config"] = subtitle_config;
          if (props.script_line_tag_id != "my") {
            state.scriptForm["script_line_tag_id"] = props.script_line_tag_id;
          }
        }
      }
    );

    watch(
      () => store.getters.clipJSON?.script_data?.subtitle_config,
      (val) => {
        state.scriptForm["subtitle_config"] = val;
      },
      {
        deep: true,
        immediate: true,
      }
    );

    return {
      ...toRefs(state),
      handleClose,
      deleteCard,
      addCard,
      getAudioConfig,
      handleAudioConfig,
      handleSubTitle,
      closeSubTitle,
      addThisLines,
      deleteLines,
      closeLines,
      handleOk,
      generateAudio,
      handleRadioChange,
      previewAudio,
      closePreview,
    };
  },
});
</script>

<style lang="less">
.popover_con {
  .ss-popover-inner-content {
    background-color: #333 !important;
    padding: 0;
  }

  .ss-popover-arrow-content {
    background-color: #333 !important;
  }

  .ss-tooltip-inner {
    background-color: #333 !important;
    color: #ffffff;
  }
}
</style>

<style lang="less" scoped>
.pop_operate_con {
  display: flex;
  flex-direction: column;
}

.top_con {
  display: flex;
}

.lines_con {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;

  .content_title {
    width: 45%;
    color: #8d8d91;
  }

  .content_txt {
    width: 55%;
    color: #8d8d91;
  }
}

.lines_item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 5px;

  .left_lines_content {
    width: calc(45% - 30px);
    height: 32px;
    padding: 8px;
    background: #fafafc;
    border-radius: 4px;
    font-size: 12px;
    color: #333;
    line-height: 17px;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    display: inline-block;
    overflow: hidden;
  }

  .lines_contact_icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
  }

  .right_lines_audio {
    width: calc(55%);
    height: 32px;
    padding: 0 14px;
    background: #fafafc;
    border-radius: 4px;
    font-size: 12px;
    color: #333;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .left_player_icon {
      display: flex;
      align-items: center;
      justify-content: space-between;

      .duration {
        margin-left: 5px;
      }
    }

    .right_set_icon {
    }
  }
}

.form_con {
  display: flex;
  align-items: center;
  margin-left: 10px;

  .form_title {
    color: #333;
    font-weight: bold;
  }

  .form_desc {
    color: #999;
    font-size: 12px;
    margin-left: 10px;
  }
}

.card_title {
  display: flex;
  align-items: center;
}

.scene_time {
  display: flex;
  align-items: center;
}
</style>
